#pragma once

#include "lp_conf.h"

#ifdef LP_WINDOWS
#include <WinSock2.h>
#include <ws2tcpip.h>
#include <Windows.h>
#pragma comment(lib, "ws2_32.lib")

#define LPSOCK_FD            SOCKET
#define LPSOCK_ERROR         SOCKET_ERROR
#define LPSOCK_INVALID       INVALID_SOCKET
#define LPSOCK_NO_ERROR      NO_ERROR

#else
#include <sys/socket.h>
#define LPSOCK_FD            int
#define LPSOCK_ERROR         -1
#define LPSOCK_INVALID       -1
#define LPSOCK_NO_ERROR      0

#endif


#undef LPSOCK_USE_EPOLL
#undef LPSOCK_USE_KQUEUE

#ifdef LPSOCK_USE_SELECT
#else

    #ifdef LP_WINDOWS
        #define LPSOCK_USE_SELECT
    #endif

    #ifdef LP_LINUX
        #define LPSOCK_USE_EPOLL
    #endif

    #ifdef LP_APPLE
        #ifdef LPSYS_MACOS
            #define LPSOCK_USE_KQUEUE
        #endif
        #ifdef LPSYS_IOS
            #define LPSOCK_USE_SELECT
        #endif
    #endif

    #ifdef LP_ANDROID
        #define LPSOCK_USE_SELECT
    #endif

#endif // #ifndef LPSOCK_USE_SELECT




#ifdef LPSOCK_USE_SELECT
#ifndef LPSYS_WIN
#include <sys/select.h>
#endif

#define LPSOCKETPOLL_READ   (1)
#define LPSOCKETPOLL_WRITE  (1 << 1)
#define LPSOCKETPOLL_ERROR  (1 << 2)
#define LPSOCKETPOLL_BE_ERROR (1 << 3)
#endif


#ifdef LPSOCK_USE_EPOLL
#include <sys/epoll.h>

#define LPSOCKETPOLL_READ   EPOLLIN
#define LPSOCKETPOLL_WRITE  EPOLLOUT
#define LPSOCKETPOLL_ERROR  (EPOLLERR | EPOLLHUP)
#endif


#ifdef LPSOCK_USE_KQUEUE
#include <sys/event.h>

#define LPSOCKETPOLL_READ   1 //EVFILT_READ
#define LPSOCKETPOLL_WRITE  2 //EVFILT_WRITE
#define LPSOCKETPOLL_ERROR  0
#endif

typedef struct LPSocketEvent LPSocketEvent;
struct LPSocketEvent{
    LPSOCK_FD fd;
    void * ud;
    int evt;
    LPSocketEvent * next;
};

typedef struct LPSocketPoll LPSocketPoll;

LP_API LPSocketPoll *
lpNewSocketPoll ();

LP_API void
lpFreeSocketPoll (LPSocketPoll * poll);

LP_API int
lpRegInSocketPoll (LPSocketPoll * poll, LPSOCK_FD fd, int e, void * ud);

LP_API int
lpDelInSocketPoll (LPSocketPoll * poll, LPSOCK_FD fd);

LP_API int
lpSetEvtInSocketPoll (LPSocketPoll * poll,
            LPSOCK_FD fd, int evt, void * ud);

LP_API int
lpWaitSocketPollEvt (LPSocketPoll * poll, 
    LPSocketEvent* evts, int max, int timeout);

LP_API uint32_t
lpCountSocketPoll (LPSocketPoll * poll);

